﻿/*
 * Created by SharpDevelop.
 * User: phtrung
 * Date: 4/8/2009
 * Time: 4:01 PM
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.IO;
using popLib;
using popLib.ExtensionClass;
using System.Reflection;

namespace DesktopSidebar
{
	/// <summary>
	/// Description of MainForm.
	/// </summary>
	public partial class MainForm : SidebarContainer
	{	
		int nextHeight;
		TransparentForm bgForm;
		Profile ini_config;
		
		List<SidebarGadget> gadgets = new List<SidebarGadget>();
		string file_config 		= FileLib.getFullPath( "setting.ini" );
		
		string dir_background	= FileLib.getFullPath( "Backgrounds" );
		string dir_gadget		= FileLib.getFullPath( "Gadgets" );
		
		
		
		public MainForm()
		{
			InitializeComponent();	
						
			initConfig();
			
			ReloadSidebar();
		}
		
		void initConfig(){
			//init default setting
			ini_config = ProfileLib.initProfile( ProfileLib.ProfileType.Ini, file_config );
			if(!File.Exists(file_config)){
				ini_config.setValue( "Setting", "Width", 		"160" );
				ini_config.setValue( "Setting", "Background", 	"Type" );
				ini_config.setValue( "Setting", "Position", 	"Right" );
				ini_config.setValue( "Setting", "LoadGadgets", 	"" );
			}
			
			//init background list
			string[] pngFiles = FileLib.getFileList( dir_background, "*.png", true, FileLib.SearchOption.FileOnly );
			foreach( string png in pngFiles ){
				string name = Path.GetFileNameWithoutExtension(png);
				name = name.IndexOf("(") > 0 ? name.Substring(0, name.IndexOf("(")) : name;
				ini_config.setValue( "Backgrounds", name , png.Replace( dir_background+"\\", "") );
			}
			
			//init gadget list
			string[] gadgetFolders = FileLib.getFileList( dir_gadget, "*", false, FileLib.SearchOption.FolderOnly );
			foreach( string gadget in gadgetFolders ){
				string[] dlls = FileLib.getFileList(gadget, "*.dll", false, FileLib.SearchOption.FileOnly );
				if( dlls.Length > 0 ){
					ini_config.setValue( "Gadgets", Path.GetFileNameWithoutExtension(gadget) , Path.GetFileName(dlls[0]) );
				}
			}
			
		
			
			//init directories
			if( !Directory.Exists(dir_background) ) Directory.CreateDirectory(dir_background);
			if( !Directory.Exists(dir_gadget) ) Directory.CreateDirectory(dir_gadget);
			
			//init size and location
			this.Width 		= NumberLib.getInt( ini_config.getValue( "Setting", "Width" ) ) < 160 ? 160 : NumberLib.getInt( ini_config.getValue( "Setting", "Width" ) );
			this.Height 	= Screen.PrimaryScreen.Bounds.Height;			
			this.Location   = ini_config.getValue( "Setting", "Position" ) == "Right" ? new Point( Screen.PrimaryScreen.Bounds.Width - this.Width, 0 ) : new Point( 0, 0 );
			
			//init background
			TransparentFormOption options = new TransparentFormOption();
			options.ShowTitle = options.IsHandleOpacity = options.IsWindow = false;
			options.StickBorderType = StickBorderType.All;
			
			switch( ini_config.getValue( "Setting", "Background" ) ){
				case "none":
					bgForm = FormLib.setTransparentForm( this, new Bitmap(100,100), 255, options );
					break;
				case "default1":
					bgForm = FormLib.setTransparentForm( this, 255, FormBackground.VistaWhite, options );
					break;
				case "default":
					bgForm = FormLib.setTransparentForm( this, 255, FormBackground.VistaBlue, options );
					break;
				default:
					string name = ini_config.getValue( "Setting", "Background" );
					string png  = FileLib.getFullPath( "Backgrounds\\" + ini_config.getValue( "Backgrounds", name ) );
					
					if( StringLib.isValid( png ) && File.Exists(png) ){
						string[] pads = StringLib.subStringBetween( Path.GetFileNameWithoutExtension(png), "(", ")", 0 ).Split(',');
						if( pads.Length == 1 ){
							options.Padding = new Padding( NumberLib.getInt(pads[0]) );
						}else if(pads.Length > 1){
							options.Padding = new Padding( 
							                              pads.Length >= 1 ? NumberLib.getInt(pads[0]) : NumberLib.getInt(pads[0]),
							                              pads.Length >= 1 ? NumberLib.getInt(pads[1]) : NumberLib.getInt(pads[0]),
							                              pads.Length >= 1 ? NumberLib.getInt(pads[2]) : NumberLib.getInt(pads[0]),
							                              pads.Length >= 1 ? NumberLib.getInt(pads[3]) : NumberLib.getInt(pads[0])
							                             );
						}					
						bgForm = FormLib.setTransparentForm( this, png, 255, options );
					}else{
						bgForm = FormLib.setTransparentForm( this, 255, FormBackground.VistaBlue, options );
					}
				break;
			}
			
			
		}
		
		void loadGadget( string filename ){
			
			filename = filename.Trim();
			
			
			if( filename.StartsWith("[") && filename.EndsWith("]") ){
				filename = Path.Combine( dir_gadget, filename.Substring(1,filename.Length-2) );				
			}else if( !Path.IsPathRooted(filename) ){
				filename = FileLib.getFullPath( filename );
			}
						
			if( !File.Exists( filename ) ) return;
			
			Assembly assembly = Assembly.LoadFile( filename );
			foreach (Type type in assembly.GetExportedTypes())
			{				
			    if ( type.GetInterface("ISidebarGadget", true) != null)
			    {
			        SidebarGadget obj = (SidebarGadget)type.InvokeMember(null,        
					BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic |
					BindingFlags.Instance | BindingFlags.CreateInstance, null, null , new object[]{ this });
			    	
					gadgets.Add( obj );
					UserControl child 	= (UserControl)obj.InitGadget();
					child.Location 		= new Point( this.Width/2 - child.Width/2, nextHeight );
					nextHeight 			+= child.Height + 5;
					this.Controls.Add( child );
					drawControlBackground( child );
			    }
			}
		}
		
				
		public override void ShowBalloonTip( string title, string message, ToolTipIcon toolTipIcon){
			nfi_tray.ShowBalloonTip( 5000, title, message, toolTipIcon );
		}
		
		public override void ReloadSidebar(){
			prepareBackground();
			string[] gadgets = StringLib.splitByAny( ini_config.getValue("Setting", "LoadGadgets") , ",;|" );
			foreach( string gadget in gadgets ) loadGadget( gadget );
			reDrawForm();
		}
		
		Bitmap bgTemp;
		Graphics painter;
		void prepareBackground(){
			Controls.Clear();
			foreach( SidebarGadget obj in gadgets ) obj.Dispose();
			gadgets.Clear();
			
			nextHeight 		= 20;
			bgForm.Visible 	= this.Visible = false;
			bgTemp 			= new Bitmap(bgForm.Width, bgForm.Height);
			painter 		= Graphics.FromImage(bgTemp);
			painter.DrawImage( bgForm.bmpBackground, new Point(0,0) );
		}
		void drawControlBackground( Control control ){
			if( control.BackgroundImage == null ) return;
			Bitmap bitmap = (Bitmap)control.BackgroundImage;
			control.BackgroundImage = null;		
			painter.DrawImage( bitmap, control.Left, control.Top, control.Width, control.Height );
		}
		void reDrawForm(){			
			bgForm.reDrawBackground( bgTemp );			
			bgForm.Visible = this.Visible = true;
			bgTemp.Dispose();
			GC.Collect();
		}
		
		void ActionEvent(object sender, EventArgs e)
		{
			string name = sender.GetType().Name == "ToolStripMenuItem" ? ((ToolStripMenuItem)sender).Name : ((Control)sender).Name ;
			switch( name.ToLower() ){
				case "lbl_add": break;
				case "mit_close": this.Close(); break;
				case "mit_hide": break;
			}
		}
		
		void Nfi_trayMouseClick(object sender, MouseEventArgs e)
		{
			if( e.Button == MouseButtons.Left ) ActivateSidebar();
		}
	}
	
}
